package glpm

import (
	"context"
	"fmt"
	"strings"
)

// YumManager YUM包管理器实现
type YumManager struct {
	*BaseManager
}

// NewYumManager 创建YUM包管理器
func NewYumManager(config *ManagerConfig) *YumManager {
	base := NewBaseManager("yum", config)
	return &YumManager{
		BaseManager: base,
	}
}

// Install 安装包
func (ym *YumManager) Install(ctx context.Context, packages []string) error {
	if len(packages) == 0 {
		return fmt.Errorf("需要指定要安装的包名")
	}
	
	args := []string{"install", "-y"}
	args = append(args, packages...)
	
	_, err := ym.executeCommand(ctx, args...)
	return err
}

// Remove 移除包
func (ym *YumManager) Remove(ctx context.Context, packages []string) error {
	if len(packages) == 0 {
		return fmt.Errorf("需要指定要移除的包名")
	}
	
	args := []string{"remove", "-y"}
	args = append(args, packages...)
	
	_, err := ym.executeCommand(ctx, args...)
	return err
}

// Update 更新包列表
func (ym *YumManager) Update(ctx context.Context) error {
	_, err := ym.executeCommand(ctx, "makecache")
	return err
}

// Upgrade 升级包
func (ym *YumManager) Upgrade(ctx context.Context, packages []string) error {
	if len(packages) == 0 {
		// 系统升级
		_, err := ym.executeCommand(ctx, "upgrade", "-y")
		return err
	}
	
	// 升级特定包
	args := []string{"update", "-y"}
	args = append(args, packages...)
	
	_, err := ym.executeCommand(ctx, args...)
	return err
}

// Search 搜索包
func (ym *YumManager) Search(ctx context.Context, pattern string) ([]PackageInfo, error) {
	output, err := ym.executeCommand(ctx, "search", pattern)
	if err != nil {
		return nil, err
	}
	
	return ym.parseSearchOutput(output)
}

// Info 获取包信息
func (ym *YumManager) Info(ctx context.Context, packageName string) (*PackageInfo, error) {
	output, err := ym.executeCommand(ctx, "info", packageName)
	if err != nil {
		return nil, err
	}
	
	return ym.parseInfoOutput(output)
}

// ListInstalled 列出已安装的包
func (ym *YumManager) ListInstalled(ctx context.Context) ([]PackageInfo, error) {
	output, err := ym.executeCommand(ctx, "list", "installed")
	if err != nil {
		return nil, err
	}
	
	return ym.parseListOutput(output)
}

// IsInstalled 检查指定包是否已安装
func (ym *YumManager) IsInstalled(ctx context.Context, packageName string) (bool, error) {
	packages, err := ym.ListInstalled(ctx)
	if err != nil {
		return false, err
	}
	
	for _, pkg := range packages {
		if pkg.Name == packageName {
			return true, nil
		}
	}
	
	return false, nil
}

// CleanCache 清理包缓存
func (ym *YumManager) CleanCache(ctx context.Context) error {
	_, err := ym.executeCommand(ctx, "clean", "all")
	return err
}

// parseSearchOutput 解析搜索输出
func (ym *YumManager) parseSearchOutput(output string) ([]PackageInfo, error) {
	var packages []PackageInfo
	
	lines := strings.Split(output, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "Loaded") || strings.HasPrefix(line, "=") {
			continue
		}
		
		// 解析格式: package.arch version repo
		parts := strings.Fields(line)
		if len(parts) >= 3 {
			nameArch := strings.Split(parts[0], ".")
			pkgName := nameArch[0]
			
			architecture := ""
			if len(nameArch) > 1 {
				architecture = nameArch[1]
			}
			packages = append(packages, PackageInfo{
				Name:         pkgName,
				Version:      parts[1],
				Architecture: architecture,
				Description:  parts[2],
			})
		}
	}
	
	return packages, nil
}

// parseInfoOutput 解析包信息输出
func (ym *YumManager) parseInfoOutput(output string) (*PackageInfo, error) {
	info := &PackageInfo{}
	
	lines := strings.Split(output, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		
		if strings.HasPrefix(line, "Name") {
			info.Name = strings.TrimSpace(strings.Split(line, ":")[1])
		} else if strings.HasPrefix(line, "Version") {
			info.Version = strings.TrimSpace(strings.Split(line, ":")[1])
		} else if strings.HasPrefix(line, "Architecture") {
			info.Architecture = strings.TrimSpace(strings.Split(line, ":")[1])
		} else if strings.HasPrefix(line, "Summary") {
			info.Description = strings.TrimSpace(strings.Split(line, ":")[1])
		}
	}
	
	return info, nil
}

// parseListOutput 解析列表输出
func (ym *YumManager) parseListOutput(output string) ([]PackageInfo, error) {
	var packages []PackageInfo
	
	lines := strings.Split(output, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "Loaded") || strings.HasPrefix(line, "Installed") {
			continue
		}
		
		// 解析格式: package.arch version @repo
		parts := strings.Fields(line)
		if len(parts) >= 2 {
			nameArch := strings.Split(parts[0], ".")
			pkgName := nameArch[0]
			
			architecture := ""
			if len(nameArch) > 1 {
				architecture = nameArch[1]
			}
			packages = append(packages, PackageInfo{
				Name:         pkgName,
				Version:      parts[1],
				Architecture: architecture,
				Status:       "installed",
			})
		}
	}
	
	return packages, nil
}